#pragma once

#include <map>
#include <vector>

#include "AbstractEntity.h"
#include "GameObjectData.h"

/* Detail entity */
#include "ObstructionEntity.h"
#include "WaterEntity.h"
#include "BridgeLeftEntity.h"
#include "BridgeCenterEntity.h"
#include "BridgeRightEntity.h"
#include "BossEntity.h"
#include "ItemEntity.h"

#include "BoatEntity.h"
#include "StoneEntity.h"
#include "BridgeEntity2.h"
#include "WaterEnemyEntity.h"
#include "BoomEntity.h"
#include "GunEnemyEntity.h"
#include "TankEntity.h"
#include "Boss3Entity.h"
#include "Boss2Entity.h"

#include "ArmyEntityFactory.h"

#include "ItemBlockEntity.h"

/*
@Description: convert GameObjectData to Entity
*/

enum ObjectType {
	TYPE_Player = 0,
	TYPE_Ground  = 1,
	TYPE_Stone = 2,
	TYPE_Bridge_State2 = 3,
	TYPE_Bridge_Left = 11,
	TYPE_Bridge_Center = 12,
	TYPE_Bridge_Right = 13,
	TYPE_Enemy = 4,
	TYPE_Enemy_Hide = 5,
	TYPE_Gun_Bird = 6,
	TYPE_Gun_Red = 7,
	TYPE_Gun_White = 8,
	TYPE_Boss = 9,
	TYPE_Water = 10,
	TYPE_Hiden_Enemy = 14,
	TYPE_Item_Pakage = 15,
	TYPE_Water_Enemy = 16,
	TYPE_Boat = 17,
	TYPE_Boss_State2 = 18,
	TYPE_Boom = 19,
	TYPE_Gun_Enemy = 20,
	TYPE_Tank = 21,
	TYPE_Boss_State3 = 22,
	TYPE_Back_Enemy = 23
};

class BridgeLeftEntity;

class EntityAdapter {
public:
	static Rect* rangeOfEffectGun;

	/* Main function to check what type of entity to be created */
	static AbstractEntity* convertFromGameObjectData(GameObjectData* objData) {
		if (objData == NULL) {
			return NULL;
		}

		// Check type of objData to create entity
		int objType = objData->Type;
		switch (objType)
		{
		case TYPE_Player:
		case TYPE_Ground:
			return new ObstructionEntity(objData->Id, _ID_MAP_STAGE1_GRASS_1, objData->rect->X, objData->rect->Y);
		case TYPE_Water:
			return new WaterEntity(objData->Id, _ID_MAP_STAGE1_WATER_1, objData->rect->X, objData->rect->Y);
		case TYPE_Bridge_Left:
			return new BridgeLeftEntity(objData->Id, _TYPE_OBS_BRIDGE_LEFT_1, objData->rect->X, objData->rect->Y);
		case TYPE_Bridge_Center:
			return new BridgeCenterEntity(objData->Id, _TYPE_OBS_BRIDGE_CENTER_1, objData->rect->X, objData->rect->Y);
		case TYPE_Bridge_Right:
			return new BridgeRightEntity(objData->Id, _TYPE_OBS_BRIDGE_RIGHT_1, objData->rect->X, objData->rect->Y);
		case TYPE_Enemy:
			return ArmyEnttiyFactory::getArmyEntity(objData->Id, _ID_ARMY_RUNNING_SOLDIER, objData->rect->X, objData->rect->Y + 50	,
				GameDeviceSingleton::getInstance()->getPlayerRect(), EntityAdapter::rangeOfEffectGun);
		case TYPE_Enemy_Hide:
			return ArmyEnttiyFactory::getArmyEntity(objData->Id, _ID_ARMY_RED_SOLDIER, objData->rect->X, objData->rect->Y,
				GameDeviceSingleton::getInstance()->getPlayerRect(), EntityAdapter::rangeOfEffectGun);
		case TYPE_Gun_Bird:
			return new ItemBlockEntity(objData->Id, _ID_ITEM_1, objData->rect->X, objData->rect->Y);
		case TYPE_Gun_Red:
			return ArmyEnttiyFactory::getArmyEntity(objData->Id, _ID_ARMY_GUN_2, objData->rect->X, objData->rect->Y,
				GameDeviceSingleton::getInstance()->getPlayerRect(), EntityAdapter::rangeOfEffectGun);
		case TYPE_Gun_White:
			return ArmyEnttiyFactory::getArmyEntity(objData->Id, _ID_ARMY_GUN_1, objData->rect->X, objData->rect->Y,
				GameDeviceSingleton::getInstance()->getPlayerRect(), EntityAdapter::rangeOfEffectGun);
		case TYPE_Boss:
			return new BossEntity(objData->Id, _ID_ARMY_BOSS_TOP_LEFT_1, objData->rect->X, objData->rect->Y);
		case TYPE_Hiden_Enemy:
			return ArmyEnttiyFactory::getArmyEntity(objData->Id, _ID_ARMY_RED_HIDDEN, objData->rect->X, objData->rect->Y,
				GameDeviceSingleton::getInstance()->getPlayerRect(), EntityAdapter::rangeOfEffectGun);
		case TYPE_Item_Pakage:
			return new ItemEntity(objData->Id, _ID_ITEM_1, objData->rect->X, objData->rect->Y, GameDeviceSingleton::getInstance()->getPlayerRect());
		case TYPE_Water_Enemy:
			return new WaterEnemyEntity(objData->Id, _ID_MAP_STAGE2_WATER_ENEMY_1, objData->rect->X, objData->rect->Y);
		case TYPE_Stone:
			return new StoneEntity(objData->Id, _ID_MAP_STAGE2_STONE_1, objData->rect->X, objData->rect->Y);
		case TYPE_Boat:
			return new BoatEntity(objData->Id, _ID_MAP_STAGE2_BOAT_1, objData->rect->X, objData->rect->Y);
		case TYPE_Bridge_State2:
			return new BridgeEntity2(objData->Id, _ID_MAP_STAGE2_BRIDGE_1, objData->rect->X, objData->rect->Y);
		case TYPE_Boss_State2:
			return new Boss2Entity(objData->Id, _ID_ARMY_BOSS_2, objData->rect->X, objData->rect->Y);
		case TYPE_Boom:
			return new BoomEntity(objData->Id, _ID_MAP_STAGE3_BOOM_1, objData->rect->X, objData->rect->Y);
		case TYPE_Gun_Enemy:
			return new GunEnemyEntity(objData->Id, _ID_MAP_STAGE3_GUN_ENEMY_1, objData->rect->X, objData->rect->Y, GameDeviceSingleton::getInstance()->getPlayerRect());
		case TYPE_Tank:
			return new TankEntity(objData->Id, _ID_MAP_STAGE3_TANK_1, objData->rect->X, objData->rect->Y, GameDeviceSingleton::getInstance()->getPlayerRect());
		case TYPE_Boss_State3:
			return new Boss3Entity(objData->Id, _ID_MAP_STAGE3_BOSS_1, objData->rect->X, objData->rect->Y);
		case TYPE_Back_Enemy:
		default:
			return NULL;
		}
	}
};
